package figure8.GUI;

import java.awt.BorderLayout;
import java.awt.Color;
import java.io.File;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.RectangleInsets;

import figure8.WAVTrack;

public class Waveform extends JPanel {
	
	int[] cords = null; 
	int val = 0;  
	float sampleRate = 0;
	AudioFormat format = null;
	XYSeries series;
	XYSeriesCollection dataSet;
	private static final int EXTERNAL_BUFFER_SIZE = 128000;
	private static int resolution = 50;
	
	public Waveform(WAVTrack track) {
		this.setLayout(new BorderLayout());
		
		series = new XYSeries("Waveform");
		dataSet = new XYSeriesCollection();
		
		JFreeChart chart = ChartFactory.createXYLineChart(null,null,null,dataSet,PlotOrientation.VERTICAL,false,true,false);
		ChartPanel chPanel = new ChartPanel(chart);
		
		chart.setPadding(new RectangleInsets(0, 0, 0, 0));
		
		XYPlot plot = chart.getXYPlot();
		ValueAxis axis = plot.getDomainAxis();
		axis.setRange(0, track.getTiming().getLength());
		plot.getRangeAxis().setVisible(false);
		plot.getDomainAxis().setVisible(false);
		chart.setBackgroundPaint(Color.WHITE);
		
		this.add(chPanel, BorderLayout.CENTER);
		
		capture(track.getFile());
	}
	
	public void capture(File soundFile){
		AudioInputStream audioInputStream = null;
		SourceDataLine sdl = null;
		DataLine.Info info = null;
		byte[] samples = new byte[EXTERNAL_BUFFER_SIZE];
		int j = 0;
		
		try{
			audioInputStream = AudioSystem.getAudioInputStream(soundFile);
			format = audioInputStream.getFormat();
			sampleRate = format.getSampleRate();
			sampleRate = (sampleRate * format.getSampleSizeInBits()) / 8;
			info = new DataLine.Info(SourceDataLine.class, format);
			sdl = (SourceDataLine) AudioSystem.getLine(info);
			sdl.open(format);
		}
		catch (Exception e){
			e.printStackTrace();
		}
		sdl.start();
		int numBytesRead = 0;
		try
		{
			int sps = 0;
			cords = new int[500];
			while ( j < 500)
			{
				cords[j] = 0;
				j++;
			}
			double increment = 1.0 / resolution;
			int y = 0;
			double x = 0;
			while (numBytesRead != -1)
			{
				numBytesRead = audioInputStream.read(samples, 0, (int) sampleRate);
				if (numBytesRead >= 0)
				{
					//sdl.write(samples, 0, numBytesRead);
					sps = 0;
					while ( sps < resolution )
					{
						int counter = 0;
						byte temp[] = new byte[(int) sampleRate / resolution];
						
							
							while ( counter < temp.length )
							{
								temp[counter] = samples[counter+(sps*((int) sampleRate / resolution))];
								counter++;
							
							}
						x = x +	increment; 					
						y = byteArrayToInt(1,temp);
						series.add(x, y);
						sps++;
					}
					dataSet.addSeries(series);			
					
				}
			}
		}
		catch (Exception e)
		{
			System.err.println(e);
		}
	}
	
	public int byteArrayToInt(int channels, byte[] data)
	{
		int[][] g_data = new int[channels][data.length/(2*channels)];
		int i = 0;
		int chanNum = 0;
		int byteNum = 0;
		int sum = 0;
		while ( byteNum < data.length){
			chanNum = 0;
			while ( chanNum < channels )
			{
				int low = (int) data[byteNum];
				int high = (int) data[byteNum+1];
				byteNum = byteNum + 2;
				int sample = (high << 8 ) + (low & 0x00ff);
				g_data[chanNum][i] = sample;
				chanNum++;
			}
			i++;
		}
	
		byteNum = 0;
		while ( byteNum < data.length/2)
		{
			sum = sum + g_data[0][byteNum];
			byteNum++;
		}
		sum = sum / data.length;
		return sum;
	}
	
}